<template>
  <van-skeleton title :row="5" v-if="!info" />
  <div class="contentMy" v-else v-html="info.body"></div>
  <div class="nav-box">
    <van-icon name="arrow-left" @click="router.go(-1)"></van-icon>
    <van-icon name="comment-o" :badge="comments"></van-icon>
    <van-icon name="good-job-o" :badge="popularity"></van-icon>
    <van-icon
      name="star-o"
      :color="isStore ? '#1989fa' : ''"
      @click="changeStore"
    ></van-icon>
    <van-icon name="share-o" color="#ccc"></van-icon>
  </div>
</template>

<script>
import { useRouter, useRoute } from "vue-router";
import { useStore } from "vuex";
import { Toast } from "vant";
import {
  reactive,
  toRefs,
  onBeforeMount,
  onBeforeUnmount,
  nextTick,
  computed,
} from "vue";
import api from "@/api";

export default {
  name: "Detail",
  setup() {
    // 使用router/route
    const router = useRouter(),
      route = useRoute(),
      store = useStore();

    // 创建响应式状态
    const state = reactive({
      id: route.params.id,
      info: null,
      comments: 0,
      popularity: 0,
    });

    // 第一次渲染之前:从服务器获取新闻详细信息 & 评论数 等
    onBeforeMount(async () => {
      let info = await api.queryNewsInfo(state.id);
      state.info = info;
      // 把获取的CSS样式动态加入到<head>中 && 插入图片
      setCss();
      nextTick(insertImage);
    });
    onBeforeMount(async () => {
      let { comments, popularity } = await api.queryNewsComments(state.id);
      state.comments = comments;
      state.popularity = popularity;
    });

    // 组件销毁之前移除动态创建的样式
    onBeforeUnmount(() => {
      let link = document.querySelector("#link");
      if (link) document.head.removeChild(link);
    });

    // 动态设置CSS样式
    const setCss = () => {
      let { css } = state.info;
      if (!css || css.length === 0) return;
      let link = document.createElement("link");
      link.id = "link";
      link.rel = "stylesheet";
      link.href = css[0];
      document.head.appendChild(link);
    };

    // 插入图片
    const insertImage = () => {
      let box = document.querySelector(".img-place-holder"),
        image = state.info.image;
      if (box) box.style.display = "none";
      if (!box || !image) return;
      let img = new Image();
      img.src = image;
      img.onload = () => {
        box.appendChild(img);
        box.style.display = "block";
      };
    };

    //=============
    // 第一次渲染之前：检测是否登录 && 如果登录还需要获取收藏列表
    onBeforeMount(async () => {
      let { isLogin, storeList } = store.state;
      if (isLogin === null) {
        isLogin = await store.dispatch("changeIsLoginAsync");
      }
      if (!isLogin) return;
      if (storeList === null) {
        storeList = await store.dispatch("queryStoreListAsync");
      }
    });

    // 创建计算属性：依托为vuex中的收藏列表，计算出当前新闻是否被收藏
    let isStore = computed(() => {
      let { storeList } = store.state;
      storeList = storeList || [];
      return storeList.some((item) => {
        return String(item.news.id) === String(state.id);
      });
    });

    // 移除收藏 & 收藏
    const changeStore = async () => {
      let { isLogin, storeList } = store.state;
      if (!isLogin) {
        // 没有登录
        Toast.fail("请您先登录~~");
        router.push("/login");
        return;
      }
      try {
        if (isStore.value) {
          // 已经收藏:移除收藏(首先找到收藏ID)
          let { id } = storeList.find((item) => {
            return String(item.news.id) === String(state.id);
          });
          // 告知服务器移除
          let { code } = await api.storeRemove(id);
          if (+code !== 0) {
            Toast.fail("移除收藏失败~~");
            return;
          }
          // 服务器移除成功,我们需要把vuex中的也移除
          Toast.success("移除收藏成功~~");
          store.commit("removeStoreList", id);
          return;
        }
        // 未收藏:收藏
        let { code } = await api.store(state.id);
        if (+code !== 0) {
          Toast.fail("收藏失败~~");
          return;
        }
        Toast.success("收藏成功~~");
        // 从服务器获取最新的收藏记录，同步到vuex中
        store.dispatch("queryStoreListAsync");
      } catch (_) {}
    };

    return {
      ...toRefs(state),
      router,
      isStore,
      changeStore,
    };
  },
};
</script>

<style lang="less" scoped>
.contentMy {
  background: #fff;
  padding-bottom: 50px;
  margin: 0;

  /deep/ .img-place-holder {
    height: 375px;
    overflow: hidden;
    img {
      display: block;
      margin: 0;
      width: 100%;
      min-height: 100%;
    }
  }
}

.van-skeleton {
  padding: 30px 15px;
}

.nav-box {
  position: fixed;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
  padding: 0 15px;
  width: 100%;
  height: 50px;
  background: #f4f4f4;

  .van-icon:nth-child(1) {
    position: relative;
    &::after {
      position: absolute;
      top: -10%;
      right: -15px;
      content: "";
      width: 1px;
      height: 120%;
      background: #d5d5d5;
    }
  }

  /deep/ .van-badge {
    background-color: transparent;
    border: none;
    color: #000;
    right: -5px;
  }
}
</style>